package hermesV3.protocols;

import hermesV3.agent.AbstractProtocol;
import hermesV3.agent.Interaction;

/**
 * Manages communication among simulation agents ({@code HubAgent},
 * {@code GlobalCoordinator} and {@code LocalCoordinator}) but also with other.
 * {@code Agent}s.<br>
 * Even if the names of the {@code Interaction}s recall the so called
 * {@code three-way handshake}, handshaking is not implemented at all, i.e. the
 * {@code Interaction}s are not used to mimic such procedure.
 * 
 * @see it.unicam.cs.cosy.bioshape.core.components.GlobalCoordinator
 * @see it.unicam.cs.cosy.bioshape.core.components.LocalCoordinator
 * @see hermesV3.services.Space.SpaceManager
 * 
 * @author Federico Buti, Gaston Alanis, Matteo Micheletti, Andrea Piermarteri
 */
public class SynProtocol extends AbstractProtocol {

	/** Auto-generated serial ID */
	private static final long serialVersionUID = 5338161764057772696L;
	/** {@code Interaction} syn */
	public static final String INTERACTIONSYN = "Syn";
	/** Response to syn {@code Interaction} */
	public static final String INTERACTIONSYNACK = "SynAck";
	/** Response to syn-ack {@code Interaction} */
	public static final String INTERACTIONACK = "Ack";
	/** Response {@code Interaction} to eventual errors */
	public static final String INTERACTIONERROR = "Error";

	/** Declares {@code Interaction}s among {@link SynProtocol} actions. */
	public SynProtocol() {
		super("SynProtocol");

		String[] parameterNameSyn = new String[1];
		parameterNameSyn[0] = "Syn";
		Class<?>[] parameterTypeSyn = new Class[1];
		parameterTypeSyn[0] = Object.class;
		Interaction syn = new Interaction(INTERACTIONSYN, INTERACTIONSYN,
				INTERACTIONSYN, parameterNameSyn, parameterTypeSyn);
		addInteraction(syn);

		String[] parameterNameSynAck = new String[1];
		parameterNameSynAck[0] = "SynAck";
		Class<?>[] parameterTypeSynAck = new Class[1];
		parameterTypeSynAck[0] = Object.class;
		Interaction synAck = new Interaction(INTERACTIONSYNACK,
				INTERACTIONSYNACK, INTERACTIONSYNACK, parameterNameSynAck,
				parameterTypeSynAck);
		addInteraction(synAck);

		String[] parameterNameAck = new String[1];
		parameterNameAck[0] = "Ack";
		Class<?>[] parameterTypeAck = new Class[1];
		parameterTypeAck[0] = Object.class;
		Interaction ack = new Interaction(INTERACTIONACK, INTERACTIONACK,
				INTERACTIONACK, parameterNameAck, parameterTypeAck);
		addInteraction(ack);

		addResponseLink(syn, synAck);
		addResponseLink(synAck, ack);

		String[] parameterNameError = new String[1];
		parameterNameError[0] = "Error";
		Class<?>[] parameterTypeError = new Class[1];
		parameterTypeError[0] = String.class;
		Interaction error = new Interaction(INTERACTIONERROR, INTERACTIONERROR,
				INTERACTIONERROR, parameterNameError, parameterTypeError);
		addInteraction(error);

		addErrorLink(syn, error);
		addErrorLink(synAck, error);
		addErrorLink(ack, error);
	}
}